package org.nf.web.embed;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.setting.yaml.YamlUtil;
import org.nf.web.config.Configure;

/**
 * @author zhu
 * @date 2024-05-14
 */
public abstract class AbstractWebServer implements WebServer{
    /**
     * 模板方法
     * @throws Exception
     */
    @Override
    public void run(Class<?> mainClass){
        // 1.解析配置，返回Configure对象
        Configure configure = initConfigure(mainClass);
        // 2.启动容器，不同的容器有不同的具体实现
        try {
            start(configure);
        } catch (Exception e) {
            throw new RuntimeException("Start server fail" + e);
        }
    }

    /**
     * 初始化配置对象，将yml的配置信息映射到configure对象中
     *
     * @return
     */
    private Configure initConfigure(Class<?> mainClass){
        String configFilePath = ClassUtil.getClassPath() + "application.yml";
        Configure configure;
        // 判断文件是否存在
        if (FileUtil.exist(configFilePath)) {
            // 解析yml并映射到Configure对象中
            configure = YamlUtil.loadByPath("application.yml",Configure.class);
            // 有可能用户只创建一个application.yml但未设置任何节点，因此返回的对象可能是null
            if (configure == null) {
                configure = new Configure();
            }
        } else {
            // 不存在则创建Configure实例
            configure = new Configure();
        }
        // 执行扫描
        configure.scan(mainClass);

        return configure;
    }

    /**
     * 抽象的启动方法，由子类做不同的实现
     * @param configure configure对象，配置信息
     * @throws Exception 运行时产生的异常
     */
    public abstract void start(Configure configure) throws Exception;
}
